package com.wxm.api.xml;

import com.wxm.api.exception.CrawlerException;
import lombok.Data;
import java.util.List;

/**
 * <p>
 * 容器基类
 * </p>
 *
 * @author wxm
 * @Date 2021/9/29
 */
@Data
public abstract class Container {
    /**
     * 最终实体类型/属性class 只有辅助类型时才会有
     */
    protected Class<?> clazz;

    /**
     * css样式的元素选择器的查询语句 用;分割多个语句
     */
    protected String select;

    /**
     * 匹配到元素后取第几个的下标 用;分割多个下标值 -1除外
     */
    protected String index;

    /**
     * 集合元素的下标取值 开始下标;结束下标
     */
    protected String collectionIndex;

    /**
     * 集合元素标记
     */
    protected Boolean collection;

    /**
     * 子属性
     */
    protected List<CrawlerFiledContainer> children;

    /**
     * 将Xml-Element进行解析(基础解析)
     * @param element Element
     * @return Container
     */
    public Container fillBaseAttribute(org.dom4j.Element element){
        String clazz = this.getStringValue(element.attributeValue("clazz"));
        if (null != clazz) {
            try {
                this.clazz = Class.forName(clazz.trim());
            }catch (ClassNotFoundException e){
                CrawlerException.error("class类型转换异常：clazz类缺失：" + clazz);
            }
        }

        this.select = this.getStringValue(element.attributeValue("select"));
        this.index = this.getStringValue(element.attributeValue("index"));
        this.collection = this.getBooleanValue(false,element.attributeValue("collection"));
        this.collectionIndex = this.getStringValue(element.attributeValue("collectionIndex"));

        //子类进行额外解析
        this.fillAttribute(element);
        //子类必须解析字段为空判断
        this.judgeAttributeNull();

        return this;
    }

    /**
     * 将Xml-Element进行解析(子类拓展属性)
     * @param element Element
     */
    protected abstract void fillAttribute(org.dom4j.Element element);

    /**
     * 对Xml-Element解析完后的 不能为null判断
     */
    protected abstract void judgeAttributeNull();

    /**
     * 将Html-Element进行解析
     * @param element Element
     * @param o o
     * @return Object
     */
    public abstract Object fillHtmlObject(org.jsoup.nodes.Element element, Object o);

    /**
     * 对传入Value进行解析 如果为null或空串则返回null 否则原样返回
     * @param value 需要解析的值
     * @return String
     */
    protected String getStringValue(String value){
        return (null == value || "".equals(value.trim())) ? null : value;
    }

    /**
     * 对传入Value进行解析 如果为null或空串则返回null 否则将字符串转为Boolean进行返回
     * @param defaultValue 默认值
     * @param value 需要解析的值
     * @return Boolean
     */
    protected Boolean getBooleanValue(Boolean defaultValue,String value){
        return null != value && !"".equals(value.trim()) ? Boolean.parseBoolean(value) : defaultValue;
    }
}
